package com.example.zhihu.service.impl;

import cn.hutool.core.date.LocalDateTimeUtil;
import com.example.zhihu.dao.SysDao;
import com.example.zhihu.entity.Token;
import com.example.zhihu.entity.User;
import com.example.zhihu.service.ITokenService;
import com.example.zhihu.service.SysService;
import com.example.zhihu.util.JwtUtil;
import com.example.zhihu.util.Md5Util;
import com.example.zhihu.util.ResponseVo;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit;
import java.util.Set;
import javax.annotation.Resource;
import org.springframework.stereotype.Service;

/**
 * Description
 *
 * @author : Charles
 * @date : 2020/1/20
 */
@Service
public class SysServiceImpl implements SysService {

  private SysDao sysDao;
  @Resource
  private ITokenService iTokenService;

  /**
   * 注入DAO
   */
  @Resource
  public void setSysDao(SysDao sysDao) {
    this.sysDao = sysDao;
  }

  /**
   * 用户注册(用户名，密码)
   *
   * @param account  用户名
   * @param password 密码
   * @return token
   */
  @Override
  public ResponseVo<String> register(String account, String password) {
    //检查用户名是否被占用
    User user = sysDao.selectByAccount(account);
    if (user != null) {
      return new ResponseVo<>(-1, "用户名被占用");
    }
    //添加用户信息
    user = new User();
    //设置用户名
    user.setAccount(account);
    //密码加密后再保存
    String salt = Md5Util.salt();
    String md5Password = Md5Util.md5(password + salt);
    user.setPassword(md5Password);
    user.setSalt(salt);
    //设置注册时间
    user.setCreateTime(LocalDate.now());
    // 添加角色
    user.setRoleId(3);
    // 添加角色名
    user.setNickname("普通用户");
    //添加到数据库
    int row = sysDao.insertSelective(user);
    //返回信息
    if (row > 0) {
      //生成token给用户
      String token = getToken(user);
      return new ResponseVo<>(0, "注册成功", token);
    } else {
      return new ResponseVo<>(-1, "注册失败");
    }
  }

  /**
   * 用户登录(用户名，密码)
   *
   * @param account  用户名
   * @param password 密码
   * @return token
   */
  @Override
  public ResponseVo<String> login(String account, String password) {
    //处理比对密码
    User user = sysDao.selectByAccount(account);
    if (user != null) {
      String salt = user.getSalt();
      String md5Password = Md5Util.md5(password + salt);
      String dbPassword = user.getPassword();
      if (md5Password.equals(dbPassword)) {
        //生成token给用户
        String token = getToken(user);
        return new ResponseVo<>(0, "登录成功", token);
      }
    }
    return new ResponseVo<>(-1, "登录失败");
  }

  private String getToken(User user) {
    // 生成token
    String token = JwtUtil.createToken(user);
    // 先判断用户是否存在token
    Token userToken = iTokenService.getByUserId(user.getId());
    if (userToken == null) {
      Token tokenObj = new Token();
      tokenObj.setUserId(user.getId());
      tokenObj.setUsername(user.getAccount());
      tokenObj.setAddTime(LocalDateTime.now());
      // 设置过期时间1小时
      tokenObj.setExpiredTime(LocalDateTimeUtil.offset(LocalDateTime.now(), 1, ChronoUnit.HOURS));
      tokenObj.setToken(token);
      iTokenService.save(tokenObj);
    } else {
      userToken.setExpiredTime(LocalDateTimeUtil.offset(LocalDateTime.now(), 1, ChronoUnit.HOURS));
      iTokenService.updateById(userToken);
    }

    return token;
  }

  /**
   * 根据account查找用户，自定义Realm中调用
   *
   * @param account
   * @return User
   */
  @Override
  public User selectByAccount(String account) {
    return sysDao.selectByAccount(account);
  }

  /**
   * 根据roleid查找用户角色名，自定义Realm中调用
   *
   * @param roleid
   * @return roles
   */
  @Override
  public String getRoleByRoleid(Integer roleid) {
    return sysDao.getRoleByroleId(roleid);
  }

  /**
   * 根据roleid查找用户权限，自定义Realm中调用
   *
   * @param roleid
   * @return Set<permissions>
   */
  @Override
  public Set<String> getPermissionsByRoleId(Integer roleid) {
    return sysDao.getPermissionsByroleId(roleid);
  }

  @Override
  public ResponseVo<String> logout(String token) {
    int user_id = JwtUtil.parseTokenUid(token);
    return new ResponseVo<String>(0, String.valueOf(user_id));
  }

}
